


import java.util.List;
import java.util.Random;
import java.util.Vector;

import javax.vecmath.Tuple3d;
import javax.vecmath.Vector3d;


/**
 * Generiert ein Mehrkoerpersystem mit einer gewuenschten Anzahl von Koerpern, die einen zufaelligen Radius,
 *  und eine zufaellige Masse und Position haben. Die Bereiche der Zufallsgenerierungen werden durch die Attribute
 *  rangeMass, rangeRadii und spaceCircumreference festgelegt.
 * @author r4smus
 *
 */
public class RandomMultiBodySystem extends MultiBodySystem {
	private int[] rangeMass; // [0] = exponent lowerLimit, [1] = exponent
								// upperLimit
	private int[] rangeRadii; // [0] = exponent lowerLimit, [1] = exponent
								// upperLimit
	private int numberOfBodies;

	public RandomMultiBodySystem(int[] rangeMass, int[] rangeRadii,
			int numberOfBodies, double massCentralBody,
			int[] spaceCircumference, int delta_t) {
		setSpaceCircumference(spaceCircumference);
		setDelta_t(delta_t);
		this.rangeMass = rangeMass;
		this.rangeRadii = rangeRadii;
		this.numberOfBodies = numberOfBodies;
		initCentralBody(massCentralBody);
		initBodyList();
		initStartVelocitySys();
		calcAccelerationSys();
	}
/**
 * Initialisiert das System mit der gewuenschten Anzahl von Koerpern mit einem zufaelligen Radius, Masse und
 * einer zufaelligen Position.
 */
	private void initBodyList() {
		List<Body> bodyList = new Vector<Body>();

		for (int i = 0; i < numberOfBodies; i++) {
			bodyList.add(new Body(calcRandomRadius(),calcRandomMass(),calcRandomPosition()));
		}
		setBodyList(bodyList);
	}

	/**
	 * Berechnet einen zufaelligen double wert im Bereich der in rangeMass
	 * gespeicherten Exponenten z.B. rangeMass[0] = 22 und rangeMass[1] = 27
	 * >> Wertebereich = 1.0*10^22 - 9.99*10^27
	 * 
	 * @return
	 */
	private double calcRandomMass() {
		int lowerLimitExp = rangeMass[0];
		int upperLimitExp = rangeMass[1];

		int randomExp = (int) ((Math.random() * (upperLimitExp + 1 - lowerLimitExp) + lowerLimitExp));
		double randomMass = ((Math.random() * 9) + 1);
		;

		randomMass *= Math.pow(10, randomExp);
		return randomMass;

	}

	/**
	 * Berechnet einen zufaelligen double wert im bereich der in rangeRadii
	 * gespeicherten Exponenten z.B. rangeRadii[0] = 22 und rangeRadii[1] = 27
	 * >> Wertebereich = 1.0*10^22 - 9.99*10^27
	 * 
	 * @return
	 */
	private double calcRandomRadius() {
		int lowerLimitExp = rangeRadii[0];
		int upperLimitExp = rangeRadii[1];

		int randomExp = (int) ((Math.random()* (upperLimitExp + 1 - lowerLimitExp) + lowerLimitExp));
		double randomRadius = ((Math.random() * 9) + 1);

		randomRadius *= Math.pow(10, randomExp);
		return randomRadius;
	}
    /**
     * Berechnet eine zufaellige Position, die in der Ausdehnung des Raumes liegt. 
     * @return randomPosition (positive und negative Werte sind moeglich)
     * 
     */
	private Vector3d calcRandomPosition() {
		int lowerLimitExp = getSpaceCircumference()[0];
		int upperLimitExp = getSpaceCircumference()[1];
		double randomDouble;
		int randomExp;
		double[] dA = new double[2];
		for (int i = 0; i < getSpaceCircumference().length; i++) {
			randomExp = (int) ((Math.random()* (upperLimitExp + 1 - lowerLimitExp) + lowerLimitExp));
			randomDouble = ((Math.random() * 9) + 1);
			randomDouble *= Math.pow(10, randomExp);		
			if(new Random().nextBoolean())	
				randomDouble *= -1;
			dA[i] = randomDouble;
		}
		return new Vector3d(dA[0],dA[1],0); //z koordinate voerst nur mal mit einer 0 init
		
	}

	
}